package adapter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import javax.naming.*;
import server.ejb.beans.*;
import server.fassade.IFassade;

public class Adapter extends UnicastRemoteObject implements IAdapter {
	private static final long serialVersionUID = 0L;

	private List<ICallbackClient> clients = new ArrayList<ICallbackClient>();
	private IFassade fassade;

	public Adapter() throws RemoteException {
		LocateRegistry.createRegistry(10990);
		LocateRegistry.getRegistry();
		// Initialize RMI registry for Callback
		try {
			Naming.rebind("rmi://localhost:10990/Adapter", this);
			System.out.println("Adapter bound");
			Context ctx = new InitialContext();
			fassade = (IFassade) ctx.lookup("FlugzeugEAR/Fassade/remote");
			System.out.println("Adapter running...");
			while(true) {
				Thread.sleep(500);
				if (fassade.isDirty()) {					
					notifyObservers();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		try {
			new Adapter();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void registerForCallback(ICallbackClient client)
	throws RemoteException {
		if (!clients.contains(client)) {
			clients.add(client);
		}
	}

	@Override
	public void unregisterFromCallback(ICallbackClient client)
	throws RemoteException {
		if (clients.contains(client)) {
			clients.remove(client);
		}
	}

	@Override
	public void notifyObservers() {
		for (ICallbackClient c: clients) {
			try {
				if (null != c){
				c.update(this);
				}
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public int createFlugzeug(String bezeichnung, int FluggesellschaftID,
			int FlugzeugTypID) {
		return fassade.createFlugzeug(bezeichnung, FluggesellschaftID, FlugzeugTypID);

	}

	@Override
	public int createFluggesellschaft(String bezeichnung) {
		return	fassade.createFluggesellschaft(bezeichnung);
	}

	@Override
	public int createFlugzeugtyp(String bezeichnung, int gebuehr) {
		return	fassade.createFlugzeugtyp(bezeichnung, gebuehr);
	}

	@Override
	public Collection<Flugzeug> getFlugzeuge()
	throws RemoteException {
		return fassade.getFlugzeug();
	}

	@Override
	public Collection<Fluggesellschaft> getFluggesellschaften()
	throws RemoteException {
		return fassade.getFluggesellschaft();
	}

	@Override
	public int createStartLandebahn(String bezeichnung) throws RemoteException {
		return fassade.createStartLandebahn(bezeichnung);
	}

	@Override
	public int createParkposition(String bezeichnung) throws RemoteException {
		return fassade.createParkposition(bezeichnung);

	}

	@Override
	public Collection<StartLandebahn> getStartLandebahnen() throws RemoteException {
		return fassade.getStartLandebahn();
	}

	@Override
	public Collection<Parkposition> getParkpositionen() throws RemoteException {
		return fassade.getParkposition();
	}

	@Override
	public Flugzeugtyp getFlugzeugtyp(int ID) throws RemoteException {
		return fassade.getFlugzeugtyp(ID);
	}

	@Override
	public Collection<Fluggesellschaft> getFluggesellschaft(String bezeichnung)throws RemoteException {

		return fassade.getFluggesellschaft(bezeichnung);
	}

	@Override
	public Collection<Flugzeug> getFlugzeug(String bezeichnung)
	throws RemoteException {
		return fassade.getFlugzeug(bezeichnung);
	}

	@Override
	public Collection<Flugzeugtyp> getFlugzeugtyp(String bezeichnung)
	throws RemoteException {
		return fassade.getFlugzeugtyp(bezeichnung);
	}

	@Override
	public Flugzeug getFlugzeug(int ID) throws RemoteException {
		return fassade.getFlugzeug(ID);
	}

	/**
	 * Used to update the clients of a reserved landing way.
	 */

	@Override
	public void startBahnBelegungAndern(int startId, boolean isBahnFree) throws RemoteException {
		fassade.startBahnBelegungAndern(startId, isBahnFree);
	}
	
	@Override
	public void startEinplanen(int startId, int fluggesellschaftId, int flugzeugId, String sollzeit) throws RemoteException {
		fassade.startEinplanen(startId, fluggesellschaftId, flugzeugId, sollzeit);
	}

	@Override
	public Parkposition getParkposition(int ID) throws RemoteException {
		return fassade.getParkposition(ID);
	}

	@Override
	public void setParkpositionOcc(int flugzeugID, int parkpositionID)
	throws RemoteException {
		fassade.setParkpositionOcc(flugzeugID, parkpositionID);

	}

	@Override
	public void setParkpositionFree(int flugzeugID, int parkpositionID)
	throws RemoteException {
		fassade.setParkpositionFree(flugzeugID, parkpositionID);

	}
	
	@Override
	public StartLandebahn getStartLandebahn(int ID) throws RemoteException {
		return fassade.getStartLandebahn(ID);
	}
	
	@Override
	public Map<Integer,Boolean> getParkingPositionSensors() throws RemoteException {
		return fassade.getParkingPositionSensors();
	}
	
	@Override
	public Map<Integer,Boolean> getLandingLaneSensors() throws RemoteException {
		return fassade.getLandingLaneSensors();
	}
	
	@Override
	public void finishStartProcess(int flugzeugId) throws RemoteException {
		 fassade.finishStartProcess(flugzeugId);
	}
}
